<?php
/**
 * Created by PhpStorm.
 * User: BlueIdeaLirui
 * Date: 2019/11/11
 * Time: 上午11:53
 */

namespace business\base\services;

final class EventService
{
    /**
     * 监听已注册的服务
     * @access private
     * @var array
     */
    protected static $listeners = [];

    /**
     * 注册需要监听的服务方法
     * @param string $name
     * @param object $reference
     * @param string $method
     */
    public static function register($name, &$reference, $method)
    {
        // 获取插件要实现的方法
        $key = get_class($reference) . '->' . $method;
        // 将插件的引用连同方法push进监听数组中
        static::$listeners[$name][$key] = array($reference, $method);
    }

    /**
     * 执行服务
     */
    public static function handler($data = [])
    {
        if (!empty(static::$listeners)) {
            foreach (static::$listeners
                     as $name => $item) {
                if (!empty($name)) {
                    static::trigger($name, $data);
                }
            }
        }
    }

    /**
     * 触发服务机制
     * @param string $name 服务的名称
     * @param mixed $data 服务的入参
     *  @return mixed
     */
    public static function trigger($name, $data = [])
    {
        // 查看要实现的服务，是否在监听数组之中
        if (isset(static::$listeners[$name])
            && is_array(static::$listeners[$name])
            && count(static::$listeners[$name]) > 0)
        {
            // 循环调用开始
            foreach (static::$listeners[$name] as $listener)
            {
                // 取出插件对象的引用和方法
                $class = & $listener[0];
                $method = $listener[1];
                if(method_exists($class, $method))
                {
                    // 动态调用插件的方法
                    call_user_func_array([$class, $method], $data);
                }
            }
        }
    }
}
